package cmd

import (
	"context"
	"fmt"
	"github.com/kevinlisr/install-levault/conf"
	"github.com/kevinlisr/install-levault/service"
	"github.com/kevinlisr/install-levault/vari"
	"github.com/spf13/cobra"
)

// 二级命令
var mysqldbCmd = &cobra.Command{
	Use:   "mysql",
	Short: "mysql [query/update/download]",
	Long: `Creates the bucket with specified name
            use: minio create bucket -n testbucket
                 minio upload -u http://127.0.0.1:9000 -b testbucket -d /data/testdir`,
	RunE: func(cmd *cobra.Command, args []string) error {
		return nil
	},
}

// 三级命令
var mysqlDownloadCmd = &cobra.Command{
	Use:   "download",
	Short: "Download file from minio",
	Long: `Queries the file name in the URL from the MYSQL database 
			and downloads the file from the specified minio to the specified directory`,
	RunE: func(cmd *cobra.Command, args []string) error {
		// 初始化全局变量
		if err := loadGlobalConfig(ConfType, Format); err != nil {
			return fmt.Errorf("LoadGlobalConfig failed %s\n", ConfFile)
		}

		// 获取config配置
		conf := conf.C()
		vari.Logger.Info(fmt.Sprintf("The Database: %s tables: %s\n", conf.Mysqldb.Database, conf.Mysqldb.Tables))

		// 获取MYSQL_DB
		db, err := conf.Mysqldb.GetDB()
		if err != nil {
			vari.Logger.Error(fmt.Sprintf("Get MysqlDB failed %s\n", conf.Mysqldb.Host))
			return fmt.Errorf("Get MysqlDB failed %s\n", conf.Mysqldb.Host)
		}
		vari.Logger.Info(fmt.Sprintf("Get MysqlDB Success %s\n", conf.Dmdb.DataSource))

		// Get minio client
		minioClient, err := conf.Minio.Client()
		if err != nil {
			vari.Logger.Error(fmt.Sprintf("Get minio %s client failed!", conf.Minio.EndpointUrl))
			return fmt.Errorf(fmt.Sprintf("Get minio %s client failed!", conf.Minio.EndpointUrl))
		}

		// Get minio executor
		minioExec := service.NewMinioExecutor(minioClient)

		// Get Dm executor and loop download files from minio
		mysqlDbExec := service.NewMysqlDbExecutor()
		ctx := context.Background()
		if err = mysqlDbExec.DownloadMinioFile(ctx, db, minioExec, conf.Mysqldb.Tables, conf.Mysqldb.Database, FilePath); err != nil {
			vari.Logger.Error("Loop Download Minio File failed, " + err.Error())
			return err
		}
		return nil
	},
}

// 三级命令
var mysqlUpdateCmd = &cobra.Command{
	Use:   "update",
	Short: "Updates the value of the specified field in the MYSQL database",
	Long: `Updates the specified data in the MYSQL database, 
            You need to modify the value in the config.yaml.`,
	RunE: func(cmd *cobra.Command, args []string) error {
		// 初始化全局变量
		if err := loadGlobalConfig(ConfType, Format); err != nil {
			return fmt.Errorf("LoadGlobalConfig failed %s\n", ConfFile)
		}

		// 获取config配置
		conf := conf.C()
		vari.Logger.Info(fmt.Sprintf("The database: %s tables: %s", conf.Mysqldb.Database, conf.Mysqldb.Tables))

		// 获取达梦DB
		db, err := conf.Mysqldb.GetDB()
		if err != nil {
			vari.Logger.Error(fmt.Sprintf("Get MysqlDB failed %s\n", conf.Mysqldb.Host))
			return fmt.Errorf("Get MysqlDB failed %s\n", conf.Mysqldb.Host)
		}
		vari.Logger.Info(fmt.Sprintf("Get MysqlDB Success %s", conf.Mysqldb.Host))

		// Get Dm executor and loop download files from minio
		mysqlDbExec := service.NewMysqlDbExecutor()

		//db *sql.DB, dmlsqls []string, url string, username string,
		//	pwd string, dbtype string, host string, port string, miniourlOld string, miniourlNew string
		if err = mysqlDbExec.UpdateTable(db, conf.Updatemysql.Dmlsqls, conf.Updatemysql.Dburl, conf.Updatemysql.Username, conf.Updatemysql.Password, conf.Updatemysql.Dbtype,
			conf.Updatemysql.Host, conf.Updatemysql.Port, conf.Updatemysql.MiniourlOld, conf.Updatemysql.MiniourlNew); err != nil {
			vari.Logger.Error(err.Error())
			return err
		}

		return nil
	},
}

// 三级命令
var mysqlQueryCmd = &cobra.Command{
	Use:   "query",
	Short: "Query the value of the specified field in the MYSQL database",
	Long: `Query the specified data in the MYSQL database, 
            You need to modify the value in the config.yaml.`,
	RunE: func(cmd *cobra.Command, args []string) error {
		// 初始化全局变量
		if err := loadGlobalConfig(ConfType, Format); err != nil {
			return fmt.Errorf("LoadGlobalConfig failed %s\n", ConfFile)
		}

		// 获取config配置
		conf := conf.C()
		vari.Logger.Info(fmt.Sprintf("The database: %s tables: %s", conf.Mysqldb.Database, conf.Mysqldb.Tables))

		// 获取MYSQL_DB
		db, err := conf.Mysqldb.GetDB()
		if err != nil {
			vari.Logger.Error(fmt.Sprintf("Get MysqlDB failed %s %v\n", conf.Mysqldb.Host, err))
			return fmt.Errorf("Get MysqlDB failed %s %v\n", conf.Mysqldb.Host, err)
		}
		vari.Logger.Info(fmt.Sprintf("Get MysqlDB Success %s", conf.Mysqldb.Host))

		// Get Dm executor and loop download files from minio
		mysqlDbExec := service.NewMysqlDbExecutor()

		//db *sql.DB, dmlsqls []string, url string, username string,
		//	pwd string, dbtype string, host string, port string, miniourlOld string, miniourlNew string
		if err = mysqlDbExec.QueryTable(db, conf.Mysqldb.Tables, conf.Mysqldb.Database); err != nil {
			vari.Logger.Error(err.Error())
			return err
		}

		return nil
	},
}

func init() {
	RootCmd.AddCommand(mysqldbCmd)
	mysqldbCmd.AddCommand(mysqlDownloadCmd, mysqlUpdateCmd, mysqlQueryCmd)

	mysqlDownloadCmd.PersistentFlags().StringVarP(&ConfType, "config-type", "t", "file", "the service config type [file/env/etcd], mysql download -t file ")
	mysqlDownloadCmd.PersistentFlags().StringVarP(&ConfFile, "config-file", "f", "etc/config.toml", "the service config from file, mysql download -f /root/config.toml")
	mysqlDownloadCmd.PersistentFlags().StringVarP(&Format, "format", "m", "yaml", "mysql download -m yaml")
	mysqlDownloadCmd.PersistentFlags().StringVarP(&EndpointUrl, "endpointurl", "e", "endpointurl", "mysql download -e http://127.0.0.1:9000")
	mysqlDownloadCmd.PersistentFlags().StringVarP(&Schema, "schema", "s", "levault", "mysql download -s TEST")
	mysqlDownloadCmd.PersistentFlags().StringVarP(&FilePath, "file-path", "d", "/tmp/", "mysql download -d /tmp/")

	mysqlUpdateCmd.PersistentFlags().StringVarP(&ConfType, "config-type", "t", "file", "the service config type [file/env/etcd], mysql update -t file ")
	mysqlUpdateCmd.PersistentFlags().StringVarP(&ConfFile, "config-file", "f", "etc/config.toml", "the service config from file, mysql update -f /root/config.toml")
	mysqlUpdateCmd.PersistentFlags().StringVarP(&Format, "format", "m", "yaml", "mysql update -m yaml")
	mysqlUpdateCmd.PersistentFlags().StringVarP(&Schema, "schema", "s", "levault", "mysql update -s TEST")

	mysqlQueryCmd.PersistentFlags().StringVarP(&ConfType, "config-type", "t", "file", "the service config type [file/env/etcd], mysql update -t file ")
	mysqlQueryCmd.PersistentFlags().StringVarP(&ConfFile, "config-file", "f", "etc/config.toml", "the service config from file, mysql update -f /root/config.toml")
	mysqlQueryCmd.PersistentFlags().StringVarP(&Format, "format", "m", "yaml", "mysql update -m yaml")
	mysqlQueryCmd.PersistentFlags().StringVarP(&Schema, "schema", "s", "levault", "mysql update -s TEST")
}
